package com.meilai.project.service.personnel.org.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.personnel.org.RosterListSearchDTO;
import com.meilai.project.entity.personnel.org.*;
import com.meilai.project.entity.system.User;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.personnel.org.RosterMapper;
import com.meilai.project.service.personnel.org.*;
import com.meilai.project.service.system.UserDepartmentRelationService;
import com.meilai.project.service.system.UserService;
import com.meilai.project.vo.personnel.org.*;
import com.meilai.project.vo.system.WebUserDepartmentRelationByUserIdVO;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author 张驰
 * @date 2022/1/18 10:01
 */
@Service
public class RosterServiceImpl extends ServiceImpl<RosterMapper, Roster> implements RosterService {

    @Autowired
    private RosterFamilyMemberService rosterFamilyMemberService;
    @Autowired
    private RosterWorkExperienceService rosterWorkExperienceService;
    @Autowired
    private UserDepartmentRelationService userDepartmentRelationService;
    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private UserMobileRelationService userMobileRelationService;

    @Autowired
    private UserService userService;

    @Override
    public Page<RosterVO> selectPageList(Integer current_page, Integer page_size, RosterListSearchDTO searchDTO) {
        Page<RosterVO> page = new Page<RosterVO>(current_page, page_size);
        List<RosterVO> list = baseMapper.selectPageList(page, searchDTO);
//        if (CollectionUtils.isNotEmpty(list)) {
//            List<Long> ids = list.stream().map(RosterVO::getUser_id).collect(Collectors.toList());
//            List<WebUserDepartmentRelationByUserIdVO> relations = userDepartmentRelationService.getWebVOByUserIds(ids);
//            if (CollectionUtils.isNotEmpty(relations)) {
//                HashMap<Long, List<WebUserDepartmentRelationByUserIdVO>> depMap = new HashMap<>();
//                relations.stream().forEach(item -> {
//                    List<WebUserDepartmentRelationByUserIdVO> tempList = depMap.get(item.getUser_id());
//                    if (tempList == null) {
//                        tempList = new ArrayList<>();
//                    }
//                    tempList.add(item);
//                    depMap.put(item.getUser_id(), tempList);
//                });
//                if (depMap.size() > 0) {
//                    list.stream().forEach(item -> {
//                        List<WebUserDepartmentRelationByUserIdVO> depList = depMap.get(item.getUser_id());
//                        item.setDepartment_list(CollectionUtils.isNotEmpty(depList) ? depList : new ArrayList<>());
//                    });
//                }
//            }
//        }
        return page.setRecords(handleList(list));
    }

    // 二次处理list
    private List<RosterVO> handleList(List<RosterVO> originList) {
        if (CollectionUtils.isNotEmpty(originList)) {
            List<Long> ids = originList.stream().map(RosterVO::getUser_id).collect(Collectors.toList());
            List<WebUserDepartmentRelationByUserIdVO> relations = userDepartmentRelationService.getWebVOByUserIds(ids);
            if (CollectionUtils.isNotEmpty(relations)) {
                HashMap<Long, List<WebUserDepartmentRelationByUserIdVO>> depMap = new HashMap<>();
                relations.stream().forEach(item -> {
                    List<WebUserDepartmentRelationByUserIdVO> tempList = depMap.get(item.getUser_id());
                    if (tempList == null) {
                        tempList = new ArrayList<>();
                    }
                    tempList.add(item);
                    depMap.put(item.getUser_id(), tempList);
                });
                if (depMap.size() > 0) {
                    originList.stream().forEach(item -> {
                        List<WebUserDepartmentRelationByUserIdVO> depList = depMap.get(item.getUser_id());
                        item.setDepartment_list(CollectionUtils.isNotEmpty(depList) ? depList : new ArrayList<>());
                    });
                }
            }
        }
        if (CollectionUtils.isNotEmpty(originList)) {
            List<Long> ids = originList.stream().map(RosterVO::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(ids)) {

                HashMap<Long, List<RosterFamilyMemberVO>> familyMemberMap = new HashMap<>();
                HashMap<Long, List<RosterWorkExperienceVO>> workExperienceMap = new HashMap<>();

                List<RosterFamilyMember> familyMembers = rosterFamilyMemberService.list(new QueryWrapper<RosterFamilyMember>().in("pid", ids));
                if (CollectionUtils.isNotEmpty(familyMembers)) {
                    familyMembers.forEach(d -> {
                        RosterFamilyMemberVO vo = new RosterFamilyMemberVO();
                        BeanUtils.copyProperties(d, vo);
                        List<RosterFamilyMemberVO> _list = familyMemberMap.getOrDefault(vo.getPid(), new ArrayList<>());
                        _list.add(vo);
                        familyMemberMap.put(vo.getId(), _list);
                    });
                }

                List<RosterWorkExperience> workExperiences = rosterWorkExperienceService.list(new QueryWrapper<RosterWorkExperience>().in("pid", ids));
                if (CollectionUtils.isNotEmpty(workExperiences)) {
                    workExperiences.forEach(d -> {
                        RosterWorkExperienceVO vo = new RosterWorkExperienceVO();
                        BeanUtils.copyProperties(d, vo);
                        List<RosterWorkExperienceVO> _list = workExperienceMap.getOrDefault(vo.getPid(), new ArrayList<>());
                        _list.add(vo);
                        workExperienceMap.put(vo.getId(), _list);
                    });
                }

                originList.forEach(d -> {
                    d.setFamily_members(familyMemberMap.getOrDefault(d.getId(), new ArrayList<>()));
                    d.setWork_experiences(workExperienceMap.getOrDefault(d.getId(), new ArrayList<>()));
                });
            }
        }
        return originList;
    }

    @Override
    public RosterVO detail(Long id) {
        RosterVO vo = baseMapper.getDetailById(id);
        if (vo == null) {
            throw new CommonException("员工信息不存在");
        } else {
            List<RosterVO> list = new ArrayList<>();
            list.add(vo);
            return handleList(list).get(0);
        }
    }

    @Override
    public void exportExcel(List<Long> ids, HttpServletResponse response) throws IOException {
        List<RosterVO> list = baseMapper.getListByIds(ids);
        handleList(list);
        List<ExportRosterVO> exportRosterVOS = formatExportData(list);
        Map<String, Object> map = new HashMap<>();
        map.put("list", exportRosterVOS);
        TemplateExportParams params = new TemplateExportParams("template/花名册导出模板.xlsx");
        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("test.xlsx", "UTF-8"));
        OutputStream out = response.getOutputStream();
        workbook.write(out);
    }

    @Override
    public List<RosterVO> listRegularList() {
        List<RosterVO> rosterVOS = baseMapper.listRegularList();
        return handleList(rosterVOS);
    }

    @Override
    public RosterVO getOneByUserId(Long user_id) {
        return baseMapper.selectOneByUserId(user_id);
    }

    @Override
    public List<UserMobileRelationVO> queryUserMobile(Long user_id) {
        return userMobileRelationService.queryUserMobile(user_id);
    }

    @Override
    public Boolean addOrEdit(UserMobileRelation relation) {
        return userMobileRelationService.saveOrUpdate(relation);
    }

    @Override
    public Boolean remove(Long id) {
        return userMobileRelationService.removeById(id);
    }

    private List<ExportRosterVO> formatExportData(List<RosterVO> rosterVOList) {
        //格式化导出数据
        List<ExportRosterVO> list = new ArrayList<>();
        int index = 1;
        for (RosterVO item : rosterVOList) {
            ExportRosterVO vo = new ExportRosterVO();
            vo.setIndex(index);
            index++;
            //姓名
            if (StringUtils.isNotEmpty(item.getName())) {
                vo.setName(item.getName());
            }
            //部门职务
            if (CollectionUtils.isNotEmpty(item.getDepartment_list())) {
                List<WebUserDepartmentRelationByUserIdVO> department_list = item.getDepartment_list();
                String str = "";
                for (int i = 0; i < department_list.size(); i++) {
                    if (i == department_list.size() - 1) {
                        str += department_list.get(i).getName() + "(" + department_list.get(i).getJob() + ")";
                    } else {
                        str += department_list.get(i).getName() + "(" + department_list.get(i).getJob() + ")\n";
                    }
                }
                vo.setDepartment_list_name(str);
            }
            //性别
            if (StringUtils.isNotEmpty(item.getSex())) {
                vo.setSex(item.getSex());
            }
            //联系电话
            if (StringUtils.isNotEmpty(item.getMobile())) {
                vo.setMobile(item.getMobile());
            }
            //身份证号
            if (StringUtils.isNotEmpty(item.getId_no())) {
                vo.setId_no(item.getId_no());
            }
            //入编时间
            if (item.getComp_fill_entry_date() != null) {
                vo.setComp_fill_entry_date(item.getComp_fill_entry_date());
                LocalDate now = LocalDate.now();
                if (item.getSocial_security_date() != null && now.isAfter(item.getSocial_security_date())) {
                    int year = item.getComp_fill_entry_date().getYear() - now.getYear();
                    int month = item.getComp_fill_entry_date().getMonthValue() - now.getMonthValue();
                    if (month < 0) {
                        year -= 1;
                        month += 12;
                    }
                    String str = (year > 0 ? year + "年" : "") + (month > 0 ? month + "个月" : "");
                    vo.setWorking_years(str);
                }
            }
            //考察期
            if (item.getComp_fill_probation_start() != null && item.getComp_fill_probation_end() != null) {
                vo.setComp_fill_probation_time(item.getComp_fill_probation_start().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "至" + item.getComp_fill_probation_end().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            //是否入编
            if (item.getBe_regular() != null) {
                vo.setBe_regular(item.getBe_regular() == 1 ? "是" : item.getBe_regular() == 0 ? "否" : "未知");
            }
            //合同签订时间
            if (item.getContract_sign_at() != null) {
                vo.setContract_sign_at(item.getContract_sign_at());
            }
            //年限
            if (item.getYears_begin() != null && item.getYears_end() != null) {
                vo.setYears(item.getYears_begin().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + "至" + item.getYears_end().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            }
            //保密协议是否签订
            if (item.getSign_confidentiality_agree() != null) {
                vo.setSign_confidentiality_agree(item.getSign_confidentiality_agree() == 1 ? "签订" : item.getSign_confidentiality_agree() == 0 ? "未签订" : "未知");
            }
            //实际参保时间
            if (item.getSocial_security_date() != null) {
                vo.setSocial_security_date(item.getSocial_security_date());
            }
            //参保公司
            if (item.getSocial_security_dep_id() != null) {
                Department dept = departmentService.getById(item.getSocial_security_dep_id());
                if (dept != null) {
                    vo.setSocial_security_dep_name(dept.getName());
                }
            }
            //学历
            if (StringUtils.isNotEmpty(item.getDegree())) {
                vo.setDegree(item.getDegree());
            }
            if (item.getBirth() != null) {
                //出生年月
                vo.setDate_of_birth(item.getBirth().getYear() + "年" + item.getBirth().getMonthValue() + "月");
                //生日
                vo.setBirth(item.getBirth().getMonthValue() + "月" + item.getBirth().getDayOfMonth() + "日");
            }
            //婚姻情况
            if (StringUtils.isNotEmpty(item.getMarriage())) {
                vo.setMarriage(item.getMarriage());
            }
            //户籍
            if (StringUtils.isNotEmpty(item.getHousehold_registration())) {
                vo.setHousehold_registration(item.getHousehold_registration());
            }
            //家庭住址
            if (StringUtils.isNotEmpty(item.getHome_address())) {
                vo.setHome_address(item.getHome_address());
            }
            //紧急联系电话
            if (StringUtils.isNotEmpty(item.getUrgent_phone())) {
                vo.setUrgent_phone(item.getUrgent_phone());
            }
            //其他
            if (StringUtils.isNotEmpty(item.getOther())) {
                vo.setOther(item.getOther());
            }
            //离职时间
            if (item.getLeave_date() != null) {
                vo.setLeave_date(item.getLeave_date());
            }
            list.add(vo);
        }
        return list;
    }

    @Override
    public Boolean verifyMobile(Long relation_id, String mobile) {
        int count = userMobileRelationService.count(Wrappers.<UserMobileRelation>lambdaQuery().eq(UserMobileRelation::getMobile, mobile).ne(UserMobileRelation::getId, relation_id));
        int num = userService.count(Wrappers.<User>lambdaQuery().isNull(User::getDeleted_at).eq(User::getMobile, mobile));
        return count + num == 0;
    }
}
